compute: add response to OUTPUT
authorJoey Hess <joeyh@joeyh.name>
Fri, 7 Mar 2025 18:47:34 +0000 (14:47 -0400)
committerJoey Hess <joeyh@joeyh.name>
Fri, 7 Mar 2025 18:47:34 +0000 (14:47 -0400)
This allows rejecting output filenames that are outside the repository,
and also handles converting eg "-foo" to "./-foo" to prevent a command
that it's passed to interpreting the output filename as a dashed option.

Remote/Compute.hs
Utility/SafeCommand.hs
doc/design/compute_special_remote_interface.mdwn
doc/special_remotes/compute/git-annex-compute-imageconvert

index b6ec907bdad361e863807ff13e42f499840f3e96..d4bcd3359ae1843aafc0eb71faf9bb775a0e3680 100644 (file)
@@ -472,6 +472,10 @@ runComputeProgram (ComputeProgram program) state (ImmutableState immutablestate)
                Just (ProcessOutput f) -> do
                        let f' = toOsPath f
                        checksafefile tmpdir subdir f' "output"
+                       -- Modify filename so eg "-foo" becomes "./-foo"
+                       liftIO $ hPutStrLn (stdinHandle p) $
+                               toCommand' (File f)
+                       liftIO $ hFlush (stdinHandle p)
                        knownoutput <- case M.lookup f' (computeOutputs $ computeState result) of
                                Nothing -> return False
                                Just mk -> do
index 6f9419cd8ca8156a0e3127c88480342a588a366d..aa96bda0eafa2aab913b3e7a14c95eb9e590ed9b 100644 (file)
@@ -10,6 +10,7 @@
 module Utility.SafeCommand (
        CommandParam(..),
        toCommand,
+       toCommand',
        boolSystem,
        boolSystem',
        boolSystemEnv,
index 2c97946a81a33c1a45f3386965f63a14d83a1336..5a55e2fe2c7049a1326f573d90c9e3d05a89e2a9 100644 (file)
@@ -16,15 +16,15 @@ Whatever values the user passes to `git-annex addcomputed` are passed to
 the program in `ARGV`, followed by any values that the user provided to 
 `git-annex initremote`.
 
-To simplify the program's option parsing, any value that the user provides
-that is in the form "foo=bar" will also result in an environment variable
-being set, eg `ANNEX_COMPUTE_passes=10` or `ANNEX_COMPUTE_--level=9`.
-
 For security, the program should avoid exposing user input to the shell
 unprotected, or otherwise executing it. And when running a command, make
 sure that whatever user input is passed to it can result in only safe and
 expected behavior.
 
+To simplify the program's option parsing, any value that the user provides
+that is in the form "foo=bar" will also result in an environment variable
+being set, eg `ANNEX_COMPUTE_passes=10` or `ANNEX_COMPUTE_--level=9`.
+
 The program is run in a temporary directory, which will be cleaned up after
 it exits. Note that it may be run in a subdirectory of a temporary
 directory. This is done when `git-annex addcomputed` was run in a subdirectory
@@ -58,6 +58,12 @@ line to stdout:
 
     OUTPUT file.jpeg
 
+Then it can read a line from stdin. This will be a sanitized version of the
+output filename. It's important to use that sanitized version to avoid path
+traversal attacks, as well as problems like filenames that look like
+dashed options. If there is a path traversal attack, the program's stdin will
+be closed without a path being written to it.
+
 The filename of the output file is both the filename in the program's
 temporary directory, and also the filename that will be added to the
 git-annex repository by `git-annex compute`.
@@ -100,10 +106,9 @@ An example `git-annex-compute-foo` shell script follows:
     echo "INPUT $2"
     read input
     echo "OUTPUT $3"
-    # Prefixing with ./ makes sure that the output is treated as a
-    # filename, rather than a dashed option.
-    output="./$3"
+    read output
     echo REPRODUCIBLE
+
     if [ -n "$input" ]; then
         mkdir -p "$(dirname "$output")"
         frobnicate --passes="$ANNEX_COMPUTE_passes" <"$input" >"$output"
index 8edc6b8f24df2cf5e2462512bf5a067b29240612..16eb14da07a06ddfb38bb0a5a0406bee7a343b9c 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# git-annex compute special remote program that uses imagemagic's convert
+# git-annex compute remote program that uses imagemagic's convert
 # to convert one type of image format into another. Eg, jpeg to gif.
 # 
 # Copyright 2025 Joey Hess; licenced under the GNU GPL version 3 or higher.
@@ -14,10 +14,7 @@ fi
 echo "INPUT $1"
 read input
 echo "OUTPUT $2"
-
-# Prefixing with ./ makes sure that the output is treated as a
-# filename, rather than a dashed option.
-output="./$2"
+read output
 
 if [ -n "$input" ]; then
        mkdir -p "$(dirname "$output")"